home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / dev / c / appsource.lha / APlusPlus / libsource / AttrList.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-29  |  7.2 KB  |  248 lines

  1. /******************************************************************************
  2.  **
  3.  **   C++ Class Library for the Amiga© system software.
  4.  **
  5.  **   Copyright (C) 1994 by Armin Vogt  **  EMail: armin@uni-paderborn.de
  6.  **   All Rights Reserved.
  7.  **
  8.  **   $Source: apphome:RCS/libsource/AttrList.cxx,v $
  9.  **   $Revision: 1.14 $
  10.  **   $Date: 1994/07/31 13:13:31 $
  11.  **   $Author: Armin_Vogt $
  12.  **
  13.  ******************************************************************************/
  14.  
  15. extern "C"
  16. {
  17. #include <stdlib.h>
  18. }
  19. #include <APlusPlus/utility/AttrList.h>
  20. //#include <APlusPlus/utility/Taglist.h>
  21.  
  22.  
  23. static const char rcs_id[] = "$Id: AttrList.cxx,v 1.14 1994/07/31 13:13:31 Armin_Vogt Exp Armin_Vogt $";
  24.  
  25.  
  26. AttrList::AttrList(TagList tl)
  27. {
  28.    taglist = tl!=NULL?cloneTagItems(tl):NULL;
  29. }
  30.  
  31. AttrList::AttrList(LONG tag1Type,...)
  32. {
  33.    taglist = cloneTagItems((TagList)&tag1Type);
  34. }
  35.  
  36. AttrList::AttrList(const AttrList& from)
  37. {
  38.    taglist = from.taglist!=NULL?cloneTagItems(from.taglist):NULL;
  39. }
  40.  
  41. void AttrList::freeTagItems(TagList tlist)
  42. {
  43.    free(tlist);
  44. }
  45.  
  46. AttrList::~AttrList()
  47. {
  48.    freeTagItems(taglist);
  49. }
  50.  
  51. AttrList& AttrList::operator=(const AttrList& from) // assignment is copying
  52. {
  53.    if (this != &from)
  54.    {
  55.       freeTagItems(taglist);
  56.       taglist = from.taglist!=NULL?cloneTagItems(from.taglist):NULL;
  57.    }
  58.    return *this;
  59. }
  60.  
  61. BOOL AttrList::addAttrs(AttrList& attrs)
  62.    /* Enhance the attribute taglist with additional tags from the given
  63.       taglist in a way so that not already present tags will be added,
  64.       while already present remain untouched.
  65.       The new tags will be added at the head of the attribute taglist
  66.       with their respective values.
  67.       Already present tags are deleted in 'attrs' (set to TAG_IGNORE).
  68.       If 'attrs' contained no new tags nothing will happen.
  69.    */
  70. {
  71.    /** Set tags in the modifying taglist that are already present in the 
  72.     ** attribute taglist to TAG_IGNORE. The remaining tags are added to the 
  73.     ** attribute taglist with their values.
  74.     **/
  75.     
  76.    //puts("AttrList::addAttrs("); attrs.print(); puts(")\n");
  77.    
  78.    if (taglist==NULL)
  79.    {
  80.       taglist = cloneTagItems(attrs);
  81.       _dprintf("addAttrs to null list.\n");
  82.       return TRUE;
  83.    }  // for an empty AttrList only copy additional tags to this.
  84.  
  85.    // Check if there are any new tags..
  86.    // Set those which are already present in 'this' in 'attrs' to TAG_IGNORE.
  87.    // The number of tags that were not set to TAG_IGNORE is returned.
  88.    if (FilterTagItems(attrs.taglist,(Tag*)taglist,TAGFILTER_NOT)>0)
  89.    {
  90.       // get the end of the taglist
  91.       TagList tag = attrs.taglist;
  92.       while (tag->ti_Tag != TAG_END)
  93.          tag++;
  94.  
  95.       // concatenate additional taglist to attribute taglist
  96.       tag->ti_Tag = TAG_MORE;
  97.       tag->ti_Data = (ULONG)taglist;
  98.  
  99.       // copy concatenated taglist to a private memory (removes TAG_MORE)
  100.       TagList newTL;
  101.       if (NULL != (newTL = cloneTagItems(attrs.taglist)) )
  102.       {
  103.          // free old private attribute taglist copy
  104.          freeTagItems(taglist);
  105.  
  106.          taglist = newTL;  // set to new concatenated attribute taglist.
  107.          //puts("added. result is "); print(); puts("\n");
  108.          return TRUE;
  109.       }
  110.       else puterr("OUT_OF_MEMORY");
  111.    }
  112.    else _dprintf("no additional tags found\n");
  113.  
  114.    return FALSE;
  115. }
  116.  
  117. BOOL AttrList::updateAttrs(const AttrList& attrlist)
  118.    /* updates the tag data in 'this' of tags present in both 'this'
  119.       and 'attrlist' with the corresponding tag data in attrlist.
  120.       Returns TRUE if any tags adopted new values.
  121.    */
  122. {
  123.    BOOL changed = FALSE;   // any changes done
  124.    AttrManipulator next(*this);
  125.    AttrIterator read(attrlist);
  126.  
  127.    _dprintf("IntuiObject::writeTags : ");
  128.    while (read())
  129.    {
  130.       if (next.findTagItem(read.tag()) )
  131.       {
  132.          if (read.data() != next.data())
  133.          {
  134.             next.writeData(read.data());
  135.             changed = TRUE;
  136.          }
  137.       }
  138.    }
  139.    if (!changed)
  140.    {
  141.       _dprintf(" no changes.\n");
  142.    }
  143.    else
  144.    {
  145.       _dprintf("\n");
  146.    }
  147.    return changed;
  148. }
  149.  
  150. ULONG AttrList::mapAttrs(const AttrList& mapAt)
  151.    /* Maps taglist according to mapAt. All tags that are not appearing
  152.       in the mapAt list are being deleted (set to TAG_IGNORE). Still remaining
  153.       valid tags will be mapped to the new tag identifiers in the mapAt list.
  154.    */
  155. {
  156.    MapTags(taglist,mapAt.taglist,FALSE);
  157.    // include miss is FALSE, so unmatched tags are being deleted.
  158.    // ERROR: MapTags() does NOT remove unmatched tags!!!!
  159.    // Bug fix: use subsequent FilterTagItems().
  160.    return filterAttrs(mapAt);
  161.    //return 1L;
  162. }
  163. ULONG AttrList::mapAttrs(TagList mapList)
  164. {
  165.    MapTags(taglist,mapList,FALSE);
  166.    return filterAttrs(mapList);
  167. }
  168.  
  169. ULONG AttrList::filterAttrs(const AttrList& filterAt, int filter)
  170.    /* Filters taglist according to FilterTagItems logic: 
  171.       TAGFILER_AND : Preserve only those tags in 'this' list that are also
  172.          present in the 'filterAt' list.
  173.       TAGFILTER_NOT : Remove all tags from 'this' list that are not within
  174.          the 'filterAt' list (set to TAG_IGNORE).
  175.       The number of tags that are not set to TAG_IGNORE is returned.
  176.    */
  177. {
  178.    return FilterTagItems(taglist,(Tag*)filterAt.taglist,(ULONG)filter);
  179. }
  180.  
  181. ULONG AttrList::filterAttrs(TagList filterList)
  182. {
  183.    return FilterTagItems(taglist,(Tag*)filterList,TAGFILTER_AND);
  184.  
  185. }
  186.  
  187. TagList AttrList::cloneTagItems(TagList source)
  188.    /* This method is a replacement for the Utility/CloneTagItems() function.
  189.       It has the advantage to allocate memory with malloc() which is
  190.       faster than AllocMem() and causes less memory fragmentation.
  191.    */
  192. {
  193.    TagList oldTaglist = taglist;    // preserve 'this' taglist
  194.    {
  195.       taglist = source;                // and store the taglist to copy
  196.       AttrIterator next(*this);        // so we can use an AttrIterator
  197.       int tCount = 0;
  198.  
  199.       // run the taglist that is to be cloned and count the tag items
  200.       while ( next() ) tCount++;
  201.       tCount++;   // reserve one TagItem for the TAG_END
  202.  
  203.       // allocate memory for the counted number of tag items
  204.       if (NULL != (source = (TagList)malloc(tCount*sizeof(struct TagItem)) ) )
  205.       {
  206.          TagList tl = source;
  207.  
  208.          next.reset();
  209.          while ( next() )
  210.          { tl->ti_Tag = next.tag(); tl->ti_Data = next.data(); tl++;}
  211.  
  212.          tl->ti_Tag = tl->ti_Data = TAG_END;
  213.       }
  214.    }
  215.    taglist = oldTaglist;   // restore the taglist in 'this'
  216.    return source;
  217. }
  218.  
  219. //------------------- AttrIterator methods -------------------------------------
  220. AttrIterator::AttrIterator(const AttrList& alist)
  221.    : al(&alist), atTag(alist.taglist), tstate(alist.taglist)
  222. {
  223. }
  224.  
  225. BOOL AttrIterator::findTagItem(Tag tagVal)
  226. {
  227.    /** This method assumes that NextTagItem() keeps track of the scanned taglist with
  228.     ** the 'tstate' pointer referencing to the next tag item to be fetched with NextTagItem().
  229.     ** Since NextTagItem() does not return TAG_MORE ,TAG_SKIP and TAG_END the found tag item
  230.     ** must be a user tag thus the following tag item is at the successing (TagItem*) address.
  231.     **/
  232.    if (NULL != (atTag = FindTagItem(tagVal,tstate)))
  233.    {
  234.       tstate = atTag+1; // set NextTagItem() internal track to next tag item
  235.       return TRUE;
  236.    }
  237.    else return FALSE;
  238. }
  239.  
  240. AttrManipulator::AttrManipulator(AttrList& calist)
  241.    : AttrIterator((const AttrList&)calist)
  242. {
  243. }
  244.  
  245. void AttrList::print()
  246. {
  247.    //printTaglist(taglist);
  248. }